package com.chalk.config.security;

import com.chalk.common.constant.SecurityConstants;
import com.chalk.common.util.RedisUtil;
import com.chalk.vo.TokenVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

/**
 * @date: 2019-04-02 下午 03:35
 * @author: zhaobo0119@outlook.com
 * @Descriptopn:
 */
@Component
public class JwtRedisUtil {

    @Value("${spring.application.name}")
    private String TOKEN_TITLE;

    @Value("${jwt.token-header}")
    private String ACCESS_HEADER;

    @Value("${jwt.token-refresh}")
    private String REFRESH_HEADER;

    // 选择了记住我之后的过期时间为7天 秒
    private static final long EXPIRATION = 604800L;

    @Autowired
    private RedisUtil redisUtil;


    /**
     * 创建token并缓存
     *
     * @param username
     * @param role
     * @return
     */
    public String createRedisToken(String username, String role) {
        String token = JwtTokenUtils.createToken(username, role, EXPIRATION);
        StringBuilder builder = new StringBuilder(TOKEN_TITLE);
        builder.append(":").append(ACCESS_HEADER).append(":").append(username);
        redisUtil.set(builder.toString(), token, (EXPIRATION * 1000));
        return token;
    }

    /**
     * 删除token
     *
     * @param username
     * @return
     */
    public boolean delRedisToken(String username) {
        StringBuilder builder = new StringBuilder(TOKEN_TITLE);
        builder.append(":").append(ACCESS_HEADER).append(":").append(username);
        redisUtil.delete(builder.toString());
        return true;
    }

    /**
     * 创建刷新token
     *
     * @param username
     * @return
     */
    public String createRefreshToken(String username){
        String refreshToken = JwtTokenUtils.createRefreshToken(username);
        StringBuilder builder_refresh = new StringBuilder(TOKEN_TITLE);
        builder_refresh.append(":").append(REFRESH_HEADER).append(":").append(username);
        redisUtil.set(builder_refresh.toString(), refreshToken);
        return refreshToken;
    }

    /**
     * 删除刷新token
     *
     * @param username
     * @return
     */
    public boolean delRefreshToken(String username) {
        StringBuilder builder_refresh = new StringBuilder(TOKEN_TITLE);
        builder_refresh.append(":").append(REFRESH_HEADER).append(":").append(username);
        redisUtil.delete(builder_refresh.toString());
        return true;
    }

    /**
     * 比较刷新token
     *
     * @param refreshToken
     * @return
     */
    public TokenVo CompRefreshToken(String refreshToken){
        TokenVo vo = new TokenVo();
        String username = JwtTokenUtils.getUsername(refreshToken);
        if(username == null){
            vo.setCode(-1);
            return vo;
        }
        StringBuilder builder_refresh = new StringBuilder(TOKEN_TITLE);
        builder_refresh.append(":").append(REFRESH_HEADER).append(":").append(username);
        String token = redisUtil.get(builder_refresh.toString(), String.class);
        if(refreshToken.equals(token)){
            vo.setCode(1);
            // 返回创建成功的token
            String access_token = this.createRedisToken(username, SecurityConstants.ROLE_LOGIN);
            // 返回创建成功的刷新 refreshToken
            String refresh_token = this.createRefreshToken(username);
            vo.setToken(access_token);
            vo.setRefresh(refresh_token);
            return vo;
        }else {
            vo.setCode(-2);
            return vo;
        }
    }

    /**
     * token 过期校验
     *
     * @param Token
     * @return
     */
    public boolean expiredCheck(String Token) {
        return JwtTokenUtils.isExpiration(Token);
    }

    /**
     * 通过用户名查询存不存在用户token
     *
     * @param username
     * @return
     */
    public boolean existRedisToke(String username) {
        StringBuilder builder = new StringBuilder(TOKEN_TITLE);
        builder.append(":").append(ACCESS_HEADER).append(":").append(username);
        boolean bool = redisUtil.exists(builder.toString());
        if (!bool) {
            return false;
        }
        return true;
    }

    /**
     * 通过用户名获取用户缓存token
     *
     * @param username
     * @return
     */
    public String getRedisToke(String username) {
        StringBuilder builder = new StringBuilder(TOKEN_TITLE);
        builder.append(":").append(ACCESS_HEADER).append(":").append(username);
        return redisUtil.get(builder.toString(), String.class);
    }

    /**
     * 获取token和refreshToken
     * @param username
     * @param role
     * @return
     */
    public Map<String, Object> getTokenAndRefreshToken(String username, String role){
        String token = this.createRedisToken(username, role);
        String refreshToken = this.createRefreshToken(username);
        Map<String ,Object> map = new HashMap<>(2);
        map.put("token", token);
        map.put("refresh", refreshToken);
        return map;
    }
}
